﻿Imports 地图商家采集系统

Public Class CSougou
    Inherits CMap
    Implements IMap
    Public Sub New(mapTask As Model_Task, callback As Action(Of CProductInfo))
        task = mapTask
        UpdateView = callback
    End Sub
#Region "搜狗采集方法"
    Public Sub Deal() Implements IMap.Deal
        Log($"{MapMode.SouGou.GetDescription}信息解析中...")
        Dim areas = task.Areas
        For Each area In areas
            Dim code = GetCode(area.City)
            ''通过城市码得到HTML,并获取列表页相关信息类BaiDuListInfo
            If code.IsNull() Then
                Log($"获取城市码失败,城市[[{area.City}]]采集失败!")
                Continue For
            End If
            GetProducts(code)
        Next
    End Sub
    Public Sub GetProducts(code As CityRange)
        Dim keywords = task.keyWords
        For Each k As CKeyword In keywords
            Dim FlagPageEnd As Boolean = False, Page = -1
            Dim infoCount As Integer = 0
            Dim prePage As String = ""
            Dim success As Integer = 0
            Do
                success = 0
                Page += 1
                Dim kw As String = Sy.Text.Encode.ToUnicode(k.Keyword).Replace("\", "%")
                Dim url = $"http://map.sogou.com/#c={code.X},{code.Y},{code.Level} &lq={kw}&page={Page},10"
                'Sy.Net.GetHtml(url, Cookies:=cookies)
                Sy.Net.Factory.Http(url).SetCookies(cookies)
                Dim reqUrl = "http://map.sogou.com/EngineV6/search/json"
                Dim refer = "http://map.sogou.com/"

                '加密一次Unicode,然后替换 %3A%25u7F8E%25u98DF
                Dim key = "%3A" & Sy.Text.Encode.ToUnicode(k.Keyword).Replace("\", "%25")

                '加密两次 bound%3A13174187.5%2C3720156.25%2C13270312.5%2C3775343.75%3A0
                Dim newX = code.X.ToString.Replace(code.X.ToString.Substring(2, 1), CInt(code.X.ToString.Substring(2, 1)) + 1)
                Dim newY = code.Y.ToString.Replace(code.Y.ToString.Substring(2, 1), CInt(code.Y.ToString.Substring(2, 1)) + 1)
                Dim rangeU = $"%3A{code.X}%2C{code.Y}%2C{newX}%2C{newY}%3A0"
                Dim cityName = Sy.Text.Encode.ToUnicode(code.CityName.Replace("市", "")).Replace("\", "%25")
                Dim PageInfo = Page + 1 & "%2C10"
                Dim data = $"what=keyword{key}&range=bound{rangeU}&othercityflag=1&appid=1361&thiscity={cityName}&lastcity={cityName}&userdata=3&encrypt=1&pageinfo={PageInfo}&locationsort=0&version=7.0&ad=0&level={code.Level}&exact=1&type=&attr=&order=&submittime=0&resultTypes=poi%2Cbusline&reqid={UtilsHelper.ConvertDateTimeToInt}&cb=parent.IFMS.search"
                Dim count As Integer = 1
                Dim html As String = ""
                Dim exp As Exception
                Do
                    exp = Nothing
                    html = Sy.Net.Post(reqUrl, data, refer, cookies, Encoding:=System.Text.Encoding.GetEncoding("gbk"))
                    count += 1
                Loop While exp IsNot Nothing And count < 5
                If exp Is Nothing Then
                    Dim arrSpliter = "dataid" 'tpid
                    If html.Length < 0 Or Not html.Contains(arrSpliter) Or html = prePage Then
                        Log("关键字：" & k.Keyword & "未采集到信息,请确认")
                        FlagPageEnd = True
                    Else
                        prePage = html
#Region "采集列表页信息"
                        Dim items = html.Split({arrSpliter}, StringSplitOptions.RemoveEmptyEntries)
                        For i = 1 To items.Count - 1
                            Dim item = items(i)
                            Dim address As String = ""
                            Dim county As String = ""
                            Dim workplane As String = ""
                            Dim title As String = ""
                            Dim phone As String = ""
                            Dim mobile As String = ""
                            Dim x As String = 0
                            Dim y As String = 0
#Region "地址"
                            Dim countySpliter = """county"":"""
                            If item.Contains(countySpliter) Then county = Split(item, countySpliter)(1).Split({""""}, StringSplitOptions.None)(0)
                            Dim addrSpliter = """address"":"""
                            If item.Contains(addrSpliter) Then address = Split(item, addrSpliter)(1).Split({""""}, StringSplitOptions.None)(0)
#End Region
#Region "坐标"
                            Dim xSpliter = """minx"":"
                            Dim ySpliter = """miny"":"
                            If item.Contains(xSpliter) Then x = Split(item, xSpliter)(1).Split({","}, StringSplitOptions.None)(0)
                            If item.Contains(ySpliter) Then y = Split(item, ySpliter)(1).Split({","}, StringSplitOptions.None)(0)
                            workplane = "X:" & x & "|Y:" & y
#End Region
#Region "标题"
                            Dim titleSpliter = "caption"":"""
                            If item.Contains(titleSpliter) Then title = Split(Split(item, titleSpliter)(1), """")(0)
#End Region

#Region "手机号"
                            Dim phoneSpliter = """phone"":"""
                            If item.Contains(phoneSpliter) Then mobile = Split(item, phoneSpliter)(1).Split({""""}, StringSplitOptions.None)(0).Trim
                            '座机号
                            Dim telSpliter = """tel"":"""
                            If item.Contains(telSpliter) Then phone = Split(item, telSpliter)(1).Split({""""}, StringSplitOptions.None)(0).Trim
#End Region
                            'Debug.Print(address, workplane, phone, mobile)
#Region "采集过滤,添加"
#End Region
                            If FilterResult(title, phone, mobile, address) AndAlso FilterKeywordResult(title, task.FilterKeywords) Then
                                Dim info = New CProductInfo(address, title, workplane, code.CityName, k.Keyword, MapMode.SouGou.GetDescription, url, phone, mobile, county)
                                success += If(info.Add(), 1, 0)
                                UpdateView(info)
                            End If
                        Next
#End Region
                        If items.Count <= 1 Then FlagPageEnd = True
                        If success = 0 Then FlagPageEnd = True
                    End If
                Else
                    Log("采集超时异常")
                    FlagPageEnd = True
                End If
            Loop Until FlagPageEnd
        Next
    End Sub
    Public Overloads Function GetCode(area As String) As CityRange
        Dim data = My.Resources.CityData
        Dim x As String = "", y As String = "", level As String = ""
        Dim AreaSpliter = $"""{area}"""
        If data.Contains(AreaSpliter) Then
            Dim temp = Split(data, AreaSpliter)(1)
            Dim xSpliter = "x"": """, ySpliter = "y"": """, levelSpliter = "level"":"
            If temp.Contains(xSpliter) AndAlso temp.Contains(ySpliter) Then
                x = Split(Split(temp, xSpliter)(1), """")(0).Trim
                y = Split(Split(temp, ySpliter)(1), """")(0).Trim
                level = Split(Split(temp, levelSpliter)(1), ",")(0).Trim
                Return New CityRange(x, y, level, area)
            Else
                Log("城市码解析错误")
                Return Nothing
            End If
        Else
            Log("城市码解析错误")
            Return Nothing
        End If
    End Function
#End Region
    Public Class CityRange
        Public Sub New(x As Integer, y As Integer, level As Integer, city As String)
            Me.X = x
            Me.Y = y
            Me.Level = level
            Me.CityName = city
        End Sub

        Public Property X As Integer
        Public Property Y As Integer
        Public Property Level As Integer
        Public Property CityName As String
    End Class
End Class

